package jp.ac.u_tokyo.dch.action.front;

import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import javax.servlet.http.HttpServletRequest;

import jp.ac.u_tokyo.dch.core.db.DBConnection;
import jp.ac.u_tokyo.dch.core.exceptions.DBException;
import jp.ac.u_tokyo.dch.model.db.DataSchemaDetail;
import jp.ac.u_tokyo.dch.model.db.FrontDisplayGroup;
import jp.ac.u_tokyo.dch.model.db.GroupItems;
import jp.ac.u_tokyo.dch.model.xml.DisplayDefine;
import jp.ac.u_tokyo.dch.service.DaoServiceAware;
import jp.ac.u_tokyo.dch.service.FrontService;
import jp.ac.u_tokyo.dch.service.Transaction;
import jp.ac.u_tokyo.dch.service.TreeService;
import jp.ac.u_tokyo.dch.util.common.ModoruUtil;
import jp.ac.u_tokyo.dch.util.common.CommonUtil;
import jp.ac.u_tokyo.dch.util.common.DisplayUtil;
import jp.ac.u_tokyo.dch.view.Constants;
import jp.ac.u_tokyo.dch.view.front.FrontTreeView;

import org.apache.commons.lang.xwork.StringUtils;
import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;

/**
*
* @version 1.1
*
*/
public class FrontTreeAction extends ActionSupport implements DaoServiceAware, ModelDriven<FrontTreeView> {

	/**
	 *シリアル番号
	 */
	private static final long serialVersionUID = 1L;

	/**
	 * DBコネクションオブジェクト
	 */
	private DBConnection dbconn = null;

	/**
	 * サービス
	 */
	private FrontService service = null;

	/**
	 * タイプ
	 */
	private String actionType;

	/**
	 * 画面モデル
	 */
	private FrontTreeView view = new FrontTreeView();

	/**
	 * 作成機関の概要 画面定義
	 */
	private DisplayDefine define1;
	/**
	 * 目録データ概要 画面定義
	 */
	private DisplayDefine define2;
	/**
	 * 資料群全体 画面定義
	 */
	private DisplayDefine define3;
	/**
	 * サブフォンド 画面定義
	 */
	private DisplayDefine define4;
	/**
	 * シリーズ 画面定義
	 */
	private DisplayDefine define5;
	/**
	 * アイテム 画面定義
	 */
	private DisplayDefine define6;

	/**
	 * カスタム項目リスト
	 */
	private List<DataSchemaDetail> customItemList = null;

	/**
	 * フロントディレクトリ表示設定リスト
	 */
	private List<FrontDisplayGroup> frontDisplayGroupList = null;

	/**
	 * 時間オプションリスト
	 */
	private Map<String,String> showTimeHourMap;


	/**
	 *
	 * @return 結果
	 * @throws Exception 例外
	 */
	public String list() throws Exception {

		ModoruUtil.modoruProcess(ServletActionContext.getRequest(), "/outputfront/treeset-list", ServletActionContext.getRequest().getQueryString());

		service = new FrontService(dbconn);

		frontDisplayGroupList = service.getFrontDisplayGroupList();

		return SUCCESS;
	}

	/**
	 *
	 * @return 結果
	 * @throws Exception 例外
	 */
	public String runMakeTree() throws Exception{

		TreeService service = new TreeService(dbconn);

		HttpServletRequest request = ServletActionContext.getRequest();
		String groupid = request.getParameter("id");
		service.makeTree(groupid);
		addActionMessage("資料グルーピング処理が正常終了しました。");

		return SUCCESS;
	}

	public String addStage()throws Exception {

		service = new FrontService(dbconn);

		String sort = view.getAddSort();
		String editIndex = view.getEditIndex();
		String stageFieldKeyList = view.getStageFieldKeyList();

		viewInit(service);

		List<GroupItems> list = null;

		if (Constants.LV1_SORT.equals(sort)) {

			list = view.getLv1Select();

			setFieldKeyList(list, editIndex, stageFieldKeyList);

		} else if (Constants.LV2_SORT.equals(sort)) {

			list = view.getLv2Select();

			setFieldKeyList(list, editIndex, stageFieldKeyList);

		} else if (Constants.LV3_SORT.equals(sort)) {

			list = view.getLv3Select();

			setFieldKeyList(list, editIndex, stageFieldKeyList);

		} else if (Constants.LV4_SORT.equals(sort)) {

			list = view.getLv4Select();

			setFieldKeyList(list, editIndex, stageFieldKeyList);

		} else if (Constants.LV5_SORT.equals(sort)) {

			list = view.getLv5Select();

			setFieldKeyList(list, editIndex, stageFieldKeyList);

		} else if (Constants.LV6_SORT.equals(sort)) {

			list = view.getLv6Select();

			setFieldKeyList(list, editIndex, stageFieldKeyList);

		} else {
			list = view.getCustomSelect();

			setFieldKeyList(list, editIndex, stageFieldKeyList);

		}

		view.convertToMap();

		return SUCCESS;
	}

	private void setFieldKeyList(List<GroupItems> list, String editIndex, String stageFieldKeyList) {

		GroupItems items = list.get(Integer.valueOf(editIndex));

		items.setFieldKeyList(stageFieldKeyList);
	}

	/**
	 *
	 * @return 結果
	 * @throws Exception 例外
	 */
	public String add() throws Exception {

		actionType = Constants.ADD;

		service = new FrontService(dbconn);

		viewInit(service);

		return SUCCESS;
	}

	/**
	 *
	 * @return 結果
	 * @throws Exception 例外
	 */
	public String editInit() throws Exception {

		actionType = Constants.MOD;

		service = new FrontService(dbconn);

		HttpServletRequest request = ServletActionContext.getRequest();
		String groupid = request.getParameter("id");
		viewInit(service);
		service.setOutputFrontTreeView(groupid, view);


		return SUCCESS;
	}
	/**
	 *
	 * @return 結果
	 * @throws Exception 例外
	 */
	public String copyInit() throws Exception {

		actionType = Constants.ADD;

		service = new FrontService(dbconn);

		HttpServletRequest request = ServletActionContext.getRequest();
		String groupid = request.getParameter("id");
		viewInit(service);
		service.setOutputFrontTreeView(groupid, view);

		view.getFrontDisplayGroup().setId("");

		return SUCCESS;
	}
	/**
	 *
	 * @return 結果
	 * @throws Exception 例外
	 */
	public String deleteInit() throws Exception {

		actionType = Constants.DEL;

		service = new FrontService(dbconn);

		HttpServletRequest request = ServletActionContext.getRequest();
		String groupid = request.getParameter("id");
		viewInit(service);
		service.setOutputFrontTreeView(groupid, view);

		return SUCCESS;
	}
	/**
	 *
	 * @return 結果
	 * @throws Exception 例外
	 */
	public String modoru() throws Exception {

		service = new FrontService(dbconn);

		view.convertToMap();

		viewInit(service);

		return SUCCESS;
	}
	/**
	 *
	 * @return 結果
	 * @throws Exception 例外
	 */
	public String confirm() throws Exception {

		service = new FrontService(dbconn);

		view.convertToMap();

		viewInit(service);

		requiredCheck(view);

		if (hasErrors()) {
			return ERROR;
		}
		if (service.checkName(view)) {
			addFieldError("id", getText("duplicateMsg"));
			return ERROR;

		}

		return SUCCESS;
	}

	/**
	 *
	 * @return 結果
	 * @throws Exception 例外
	 */
	@Transaction
	public String execute() throws Exception {

		service = new FrontService(dbconn);

		view.convertToMap();

		if (Constants.ADD.equals(actionType)) {

			service.insert(view);

		} else if (Constants.MOD.equals(actionType)) {

			service.update(view);

		} else if (Constants.DEL.equals(actionType)) {

			service.delete(view);
		}

		return SUCCESS;

	}

	/**
	 * 必須チェック
	 * @param view 画面モデル
	 */
	private void requiredCheck(FrontTreeView view) {

		FrontDisplayGroup displayGroup = view.getFrontDisplayGroup();
		Map<String, GroupItems> dataMap = view.getDataMap();

		String displayName = displayGroup.getDisplayName();
		String startDate = displayGroup.getStartDate();


		if (StringUtils.isEmpty(displayName)) {
			addFieldError("id", getText("requiredstring", new String[] { "フロントディレクトリ表示設定名" }));
		}
		if (StringUtils.isEmpty(startDate)) {
			addFieldError("id", getText("requiredstring", new String[] { "開始日時" }));
		}

		boolean check = false;

		for (GroupItems items : dataMap.values()) {
			String name = items.getDisplayName();

			String fieldKey = items.getTopFieldKey();

			check = check || StringUtils.isNotEmpty(fieldKey);

			if (StringUtils.isNotEmpty(fieldKey)) {
				if (StringUtils.isEmpty(name)) {
					addFieldError("id", getText("requiredstring", new String[] { "表示名称" }));
					break;
				}
			}
		}

		if (!check) {
			addFieldError("id", getText("requiredcheck"));
		}

	}

	/**
	 * 項目キーを返す
	 * @param sort 分類
	 * @param index
	 * @return 項目キー
	 */
	public String getFieldKey(String sort, String index) {
		return CommonUtil.getFieldKey(sort, index);
	}

	/**
	 * 表示名を返す
	 * @param key 項目キー
	 * @return 表示名
	 */
	public String getDisplayName(String key) {

		return view.getDataMap().get(key).getDisplayName();
	}

	/**
	 * 段階項目キーリストを返す
	 * @param key 段階項目キーリスト
	 * @return 表示名
	 */
	public String getFieldKeyList(String key) {

		return view.getDataMap().get(key).getFieldKeyList();
	}

	/**
	 * チェックされているかを判断する
	 * @param key 項目キー
	 * @return true:チェック、false:チェックされていない
	 */
	public boolean isChecked(String key) {

		return view.getDataMap().get(key) != null;
	}
	 /**
	 * DBコネクションオブジェクトをセットする
	 */
	@Override
	public void setDBConnection(DBConnection con) {
		dbconn = con;

	}

	 /**
	 * 作成機関の概要定義オブジェクトを返す
	 * @return 作成機関の概要定義オブジェクト
	 */
	public DisplayDefine getDefine1() {
		return define1;
	}
	/**
	 *
	 * @param 作成機関の概要定義オブジェクト
	 */
	public void setDefine1(DisplayDefine define1) {
		this.define1 = define1;
	}
	 /**
	 *目録データ概要定義オブジェクトを返す
	 * @return 目録データ概要定義オブジェクト
	 */
	public DisplayDefine getDefine2() {
		return define2;
	}
	/**
	 *
	 * @param 目録データ概要定義オブジェクト
	 */
	public void setDefine2(DisplayDefine define2) {
		this.define2 = define2;
	}
	 /**
	 * 資料群全体定義オブジェクト
	 * @return 資料群全体定義オブジェクト
	 */
	public DisplayDefine getDefine3() {
		return define3;
	}
	/**
	 *
	 * @param 資料群全体定義オブジェクト
	 */
	public void setDefine3(DisplayDefine define3) {
		this.define3 = define3;
	}
	 /**
	 * サブフォンド定義オブジェクト
	 * @return サブフォンド定義オブジェクト
	 */
	public DisplayDefine getDefine4() {
		return define4;
	}
	/**
	 *
	 * @param サブフォンド定義オブジェクト
	 */
	public void setDefine4(DisplayDefine define4) {
		this.define4 = define4;
	}
	 /**
	 * シリーズ定義オブジェクト
	 * @return シリーズ定義オブジェクト
	 */
	public DisplayDefine getDefine5() {
		return define5;
	}
	/**
	 *
	 * @param シリーズ定義オブジェクト
	 */
	public void setDefine5(DisplayDefine define5) {
		this.define5 = define5;
	}
	 /**
	 * アイテム定義オブジェクト
	 * @return アイテム定義オブジェクト
	 */
	public DisplayDefine getDefine6() {
		return define6;
	}
	/**
	 *
	 * @param アイテム定義オブジェクト
	 */
	public void setDefine6(DisplayDefine define6) {
		this.define6 = define6;
	}

	/**
	 *
	 * @return カスタム項目リストを返す
	 */
	public List<DataSchemaDetail> getCustomItemList() {
		return customItemList;
	}

	/**
	 *
	 * @param カスタム項目リストをセット
	 */
	public void setCustomItemList(List<DataSchemaDetail> customItemList) {
		this.customItemList = customItemList;
	}

	/**
	 *
	 * @return 実行タイプ
	 */
	public String getActionType() {
		return actionType;
	}

	/**
	 *
	 * @param 実行タイプ
	 */
	public void setActionType(String actionType) {
		this.actionType = actionType;
	}

	/**
	 *
	 * @return フロントディレクトリ表示設定リストを返す
	 */
	public List<FrontDisplayGroup> getFrontDisplayGroupList() {
		return frontDisplayGroupList;
	}

	/**
	 *
	 * @param フロントディレクトリ表示設定リスト
	 */
	public void setFrontDisplayGroupList(
			List<FrontDisplayGroup> frontDisplayGroupList) {
		this.frontDisplayGroupList = frontDisplayGroupList;
	}

	/**
	 * 画面モデルを返す
	 */
	@Override
	public FrontTreeView getModel() {
		return view;
	}

	/**
	 * 画面に表示する項目を取得する
	 * @param service フロントサービス
	 * @throws DBException
	 */
	private void viewInit(FrontService service) throws DBException {

		define1 = DisplayUtil.getItemDefine(Constants.LV1_SORT);
		define2 = DisplayUtil.getItemDefine(Constants.LV2_SORT);
		define3 = DisplayUtil.getItemDefine(Constants.LV3_SORT);
		define4 = DisplayUtil.getItemDefine(Constants.LV4_SORT);
		define5 = DisplayUtil.getItemDefine(Constants.LV5_SORT);
		define6 = DisplayUtil.getItemDefine(Constants.LV6_SORT);

		customItemList = service.getCustomSchemaDataList();
	}

	/**
	 * 時間００～２４まで作成する
	 * @return
	 */
	public Map<String, String> getShowTimeHourMap() {
		showTimeHourMap = new TreeMap<String, String>();
		for(int i =0 ; i < 24 ; i++){
			String hour =StringUtils.leftPad(String.valueOf(i), 2,"0");
			showTimeHourMap.put(hour, hour);
		}
		return showTimeHourMap;
	}

}
